#include "types.h"
#include "sbi.h"

// 实现SBI统一调用接口
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
                        unsigned long arg1, unsigned long arg2,
                        unsigned long arg3, unsigned long arg4,
                        unsigned long arg5)
{
    struct sbiret ret;
    
    register uint64 a0 asm ("a0") = (uint64)(arg0);
    register uint64 a1 asm ("a1") = (uint64)(arg1);
    register uint64 a2 asm ("a2") = (uint64)(arg2);
    register uint64 a3 asm ("a3") = (uint64)(arg3);
    register uint64 a4 asm ("a4") = (uint64)(arg4);
    register uint64 a5 asm ("a5") = (uint64)(arg5);
    register uint64 a6 asm ("a6") = (uint64)(fid);
    register uint64 a7 asm ("a7") = (uint64)(ext);
    
    asm volatile ("ecall"
                  : "+r" (a0), "+r" (a1)
                  : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
                  : "memory");
    
    ret.error = a0;
    ret.value = a1;
    
    return ret;
}

void sbi_set_timer(uint64 stime_value)
{
    sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 0, 0, 0, 0);
}

void sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base)
{
    sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, hart_mask, hart_mask_base, 0, 0, 0, 0);
}

void sbi_remote_fence_i(unsigned long hart_mask, unsigned long hart_mask_base)
{
    sbi_ecall(SBI_EXT_RFENCE, 0, hart_mask, hart_mask_base, 0, 0, 0, 0);
}

void sbi_shutdown(void)
{
    sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_SYSTEM_RESET, 0, 0, 0, 0, 0, 0);
}

// 启动核：将核启动到start_addr，并传递opaque参数
struct sbiret sbi_hart_start(unsigned long hartid, unsigned long start_addr, unsigned long opaque)
{
    struct sbiret ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, hartid, start_addr, opaque, 0, 0, 0);
    return ret;
}

// Legacy console functions (for older SBI versions)
void sbi_console_putchar(int ch)
{
    sbi_ecall(0x1, 0, ch, 0, 0, 0, 0, 0);
}

int sbi_console_getchar(void)
{
    struct sbiret ret = sbi_ecall(0x2, 0, 0, 0, 0, 0, 0, 0);
    return ret.error;
}

